import { cesiumStateTuiyan, simulationStateTuiyan } from "@@/store-tuiyan/modules";
import {
  Cartesian3,
  Color,
  Entity,
  JulianDate,
  TimeInterval,
  TimeIntervalCollection,
  Math as CesiumMath,
  PolylineDashMaterialProperty,
  SampledPositionProperty,
  defined,
  DataSource,
  CallbackProperty,
  CustomDataSource,
} from "cesium";
import CustomViewer from "./CustomCesium/Core/CustomViewer";
import {
  ISideStep,
  IStepEntityInfo,
  ITrackEntityInfo,
  IEntityType,
} from "@@/typings/observation";
import moment from "moment";
import { SideEnum } from "@@/enums/observation";

interface IEntitiesTuiyan {
  [propName: string | number]: RouteEntityTuiyan;
}

/**
 * 实体轨迹
 */
interface RouteEntityTuiyan {
  id: number | string;
  name: string;
  type?: IEntityType;
  side?: SideEnum | string;
  routes: number[];
  positions: { time: JulianDate[]; data: Cartesian3[] };
}

/**
 * 绘制轨迹
 */
export default class RoutesManagerTuiyan {
  // 实体 id: 位置数组[]
  entityRoutesTuiyan: { [propName: string]: number[] };
  // DataSource
  datasourceTuiyan: DataSource;

  constructor() {
    const cesiumStoreTuiyan = cesiumStateTuiyan(),
      simulStoreTuiyan = simulationStateTuiyan(),
      customViewerTuiyan: CustomViewer | null = cesiumStoreTuiyan.getCustomViewerTuiyan;
    this.entityRoutesTuiyan = {};
    this.datasourceTuiyan = new CustomDataSource("all_path");
    this.datasourceTuiyan.show = simulStoreTuiyan.isShowPath;
    customViewerTuiyan?.viewer.dataSources.add(this.datasourceTuiyan);
  }

  /**
   * 初始创建路径
   * @param customViewer
   * @param step
   * @param visualAngle 当前视角
   */
  createInitPathTuiyan(step: ISideStep, visualAngle: string) {
    const entitiesTuiyan: IEntitiesTuiyan = {},
      /// 初始时间戳
      startStampTimeTuiyan = step.simul_time * 1000,
      startJulianTimeTuiyan = JulianDate.fromDate(moment(startStampTimeTuiyan).toDate()),
      endJulianTimeTuiyan = JulianDate.addMinutes(
        startJulianTimeTuiyan,
        1,
        new JulianDate()
      ),
      timeIntervalTuiyan = new TimeInterval({
        start: startJulianTimeTuiyan,
        stop: endJulianTimeTuiyan,
      }),
      timeIntervalCollectionTuiyan = new TimeIntervalCollection([timeIntervalTuiyan]),
      datasourceTuiyan = this.datasourceTuiyan,
      entityRoutesTuiyan = this.entityRoutesTuiyan;

    datasourceTuiyan && datasourceTuiyan.entities.removeAll();

    /// 筛选实体信息
    step.obj_list && step.obj_list.forEach((modelTuiyan) => {
      this.addEntityInfoTuiyan(entitiesTuiyan, modelTuiyan, startJulianTimeTuiyan);
    });

    // 根据实体创建动画
    for (const key in entitiesTuiyan) {
      if (Object.prototype.hasOwnProperty.call(entitiesTuiyan, key)) {
        const entityInfoTuiyan = entitiesTuiyan[key],
          entityTuiyan = this.createEntityTuiyan(
            entityInfoTuiyan,
            visualAngle,
            timeIntervalCollectionTuiyan
          );
        entityTuiyan &&
          entityTuiyan.id !== undefined &&
          datasourceTuiyan &&
          datasourceTuiyan.entities.add(entityTuiyan);
        entityInfoTuiyan.id !== undefined &&
          (entityRoutesTuiyan[entityInfoTuiyan.id] = [...entityInfoTuiyan.routes]);
      }
    }
  }

  /**
   * 创建实体
   * @param entityInfo
   */
  private createEntityTuiyan(
    entityInfoTuiyan: RouteEntityTuiyan,
    visualAngle: string,
    availability?: TimeIntervalCollection
  ) {
    const {
      id,
      name,
      side,
      type,
      positions,
      routes,
    } = entityInfoTuiyan,
      simulStoreTuiyan = simulationStateTuiyan();
    /// 动画步长为1
    let positionTuiyan: Cartesian3 | SampledPositionProperty =
      entityInfoTuiyan.positions.data[0];
    /// 动画步长超过1
    if (positions.data.length > 1) {
      positionTuiyan = new SampledPositionProperty();
      /// 位置时间序列
      positionTuiyan.addSamples(positions.time, positions.data);
    }
    if (routes.length > 2) {
      const resourceEntityTuiyan = new Entity({
        id: id + "",
        position: positionTuiyan,
        show:
          visualAngle === "all"
            ? true
            : visualAngle === "red" && (simulStoreTuiyan.entityIds.red.indexOf(id + "") !== -1)
              ? true
              : visualAngle === "blue" && (simulStoreTuiyan.entityIds.blue.indexOf(id + "") !== -1) ? true : false,
        polyline: {
          show: !(type?.m_kind === 1 && type?.m_domain === 5),
          positions: new CallbackProperty(() => {
            return Cartesian3.fromDegreesArray(routes);
          }, false),
          width: 1,
          material: new PolylineDashMaterialProperty({
            color:
              side === 1
                ? Color.RED.withAlpha(1)
                : Color.fromCssColorString("rgba(53, 181, 255, 1)"),
          }),
        },
      });
      return resourceEntityTuiyan;
    }
    return null;
  }

  /**
   * 添加实体信息
   * @param entities
   * @param model
   * @param currentTime
   * @returns
   */
  private addEntityInfoTuiyan(
    entitiesTuiyan: IEntitiesTuiyan,
    modelTuiyan: IStepEntityInfo | ITrackEntityInfo,
    currentTimeTuiyan: JulianDate
  ) {
    const { m_id, m_EntityName, m_Position, m_Side, m_Heading, m_EntityType } =
      modelTuiyan,
      cartesian3Tuiyan = Cartesian3.fromDegrees(
        m_Position?.longitude || 0,
        m_Position?.latitude || 0
      );
    if (!defined(cartesian3Tuiyan)) return;
    /// 已存在实体信息，则继续添加旋转、位置数据
    if (entitiesTuiyan[m_id]) {
      const entityTuiyan = entitiesTuiyan[m_id];
      /// 位置
      entityTuiyan.positions.time.push(currentTimeTuiyan);
      entityTuiyan.positions.data.push(cartesian3Tuiyan);
      entityTuiyan.routes.push(m_Position?.longitude || 0, m_Position?.latitude || 0);
    }
    /// 添加新实体信息
    else {
      const positionsTuiyan: { time: JulianDate[]; data: Cartesian3[] } = {
        time: [],
        data: [],
      },
        routesTuiyan: number[] = [];
      /// 位置
      positionsTuiyan.time.push(currentTimeTuiyan);
      positionsTuiyan.data.push(cartesian3Tuiyan);
      routesTuiyan.push(m_Position?.longitude || 0, m_Position?.latitude || 0);
      entitiesTuiyan[m_id] = {
        id: m_id,
        name: m_EntityName,
        side: m_Side,
        type: m_EntityType,
        positions: positionsTuiyan,
        routes: routesTuiyan,
      };
    }
  }

  /**
   * 更新路径
   * @param customViewer
   * @param step
   * @param visualAngle 当前视角
   */
  updatePathTuiyan(step: ISideStep, visualAngle: string) {
    const entitiesTuiyan: IEntitiesTuiyan = {},
      /// 初始时间戳
      startStampTimeTuiyan = step.simul_time * 1000,
      startJulianTimeTuiyan = JulianDate.fromDate(moment(startStampTimeTuiyan).toDate()),
      endJulianTimeTuiyan = JulianDate.addMinutes(
        startJulianTimeTuiyan,
        1,
        new JulianDate()
      ),
      timeIntervalTuiyan = new TimeInterval({
        start: startJulianTimeTuiyan,
        stop: endJulianTimeTuiyan,
      }),
      timeIntervalCollectionTuiyan = new TimeIntervalCollection([timeIntervalTuiyan]),
      datasourceTuiyan = this.datasourceTuiyan,
      entityRoutesTuiyan = this.entityRoutesTuiyan,
      simulStoreTuiyan = simulationStateTuiyan();

    datasourceTuiyan && datasourceTuiyan.entities.removeAll();

    // 筛选实体信息
    step.obj_list && step.obj_list.forEach((modelTuiyan) => {
      this.addEntityInfoTuiyan(entitiesTuiyan, modelTuiyan, startJulianTimeTuiyan);
    });

    const newRoutesTuiyan = {};

    // 根据实体创建动画
    for (const key in entitiesTuiyan) {
      if (Object.prototype.hasOwnProperty.call(entitiesTuiyan, key)) {
        const entityInfoTuiyan = entitiesTuiyan[key],
          entityTuiyan = datasourceTuiyan?.entities.getById(key + "");

        if (Object.prototype.hasOwnProperty.call(entityRoutesTuiyan, key)) {
          entityRoutesTuiyan[entityInfoTuiyan.id].push(...entityInfoTuiyan.routes);
          entityInfoTuiyan.routes = [...entityRoutesTuiyan[entityInfoTuiyan.id]];
        }

        if (entityTuiyan) {
          entityTuiyan.polyline &&
            (entityTuiyan.polyline.positions = new CallbackProperty(() => {
              return Cartesian3.fromDegreesArray(entityInfoTuiyan.routes);
            }, false));
          entityTuiyan.show = visualAngle === "all"
            ? true
            : visualAngle === "red" && (simulStoreTuiyan.entityIds.red.indexOf(key + "") !== -1)
              ? true
              : visualAngle === "blue" && (simulStoreTuiyan.entityIds.blue.indexOf(key + "") !== -1) ? true : false
        } else {
          let newEntityTuiyan = this.createEntityTuiyan(
            entityInfoTuiyan,
            visualAngle,
            timeIntervalCollectionTuiyan
          );
          newEntityTuiyan && datasourceTuiyan?.entities.add(newEntityTuiyan);
        }

        entityInfoTuiyan.id !== undefined &&
          (newRoutesTuiyan[entityInfoTuiyan.id] = [...entityInfoTuiyan.routes]);
      }
    }

    this.entityRoutesTuiyan = { ...newRoutesTuiyan };
    return true;
  }

  /**
   * 清空历史轨迹数据
   */
  removePathTuiyan() {
    this.entityRoutesTuiyan = Object.assign({}, {});
    this.datasourceTuiyan?.entities.removeAll();
  }

  /**
   * 移除路径
   */
  deletePathTuiyan(customViewer: CustomViewer) {
    this.entityRoutesTuiyan = {};
    this.datasourceTuiyan?.entities.removeAll();
    this.datasourceTuiyan &&
      customViewer.viewer.dataSources.remove(this.datasourceTuiyan, true);
  }

  /**
   * 切换视角
   */
  updateVisualTuiyan(visualAngle: string, entityList: string[]) {
    this.datasourceTuiyan.entities.values.forEach((entityTuiyan) => {
      entityTuiyan.show = visualAngle === "all" ? true : entityList.includes(entityTuiyan.id);
    });
  }
}

export function createRoutesManagerTuiyan() {
  return new RoutesManagerTuiyan();
}
